/// 上证系列指数: https://quote.eastmoney.com/center/gridlist.html#index_sz
/// 深证系列指数: https://quote.eastmoney.com/center/gridlist.html#index_sz
/// 中证系列指数: https://quote.eastmoney.com/center/gridlist.html#index_zzzs
///
///
///
/// 
use anyhow::Result;
use headless_chrome::browser::tab::RequestPausedDecision;
use headless_chrome::browser::transport::{ SessionId, Transport };
use headless_chrome::protocol::cdp::types::Event;
use headless_chrome::protocol::cdp::Fetch::events::RequestPausedEvent;
use headless_chrome::protocol::cdp::Fetch::GetResponseBody;
use headless_chrome::LaunchOptions;
use headless_chrome::{ Browser, protocol::cdp::Network, protocol::cdp::Page };
use std::collections::HashMap;
use std::sync::Arc;
use std::thread;

async fn intercept_pagination_api_calls() -> Result<()> {
    let browser = Browser::new(
        LaunchOptions::default_builder().build().expect("Could not find chrome-executable")
    )?;
    let tab = browser.new_tab()?;
    // Enable request interception
    let request_interceptor = Arc::new(
        move |
            transport: std::sync::Arc<Transport>,
            session_id: SessionId,
            intercepted: RequestPausedEvent
        | {
            println!("{}", intercepted.params.request.url);
            println!("{}", intercepted.params.request_id);
            if
                intercepted.params.resource_Type ==
                headless_chrome::protocol::cdp::Network::ResourceType::Xhr
            {
                println!("Resource type is XHR");

                let response_body_maybe = transport.call_method_on_target(
                    session_id,
                    GetResponseBody { request_id: intercepted.params.request_id }
                );

                match response_body_maybe {
                    Ok(response_body) => {
                        println!("Got Body");

                        println!("{}", response_body.body);

                        println!("\n-----------------------------------------\n");
                    }
                    Err(err) => println!("Failed to get Body"),
                }
            }

            RequestPausedDecision::Continue(None)
        }
    );

    tab.enable_request_interception(request_interceptor)?;

    let _ee = handle_network_events(&tab);

    // Navigate to the initial URL
    tab.navigate_to("https://quote.eastmoney.com/center/gridlist.html#index_zzzs")?;

    let mut page_number = 1;
    loop {
        // Process the current page here (not shown).

        // Wait for the new page to load.
        tab.wait_until_navigated()?;

        println!("Processed page {}", page_number);
        page_number += 1;

        // Find the next page button.
        let next_page_button = tab.wait_for_element(".next.paginate_button");
        if next_page_button.is_err() {
            println!("Next page button not found. Exiting.{:?}", next_page_button);
            break;
        }

        let next_page_button = next_page_button.unwrap();

        // Check if the next page button is disabled.
        let is_next_page_disabled = next_page_button.get_attribute_value("disabled");
        if is_next_page_disabled.is_err() {
            println!("is_next_page_disabled={:?}", is_next_page_disabled);
            break;
        }

        let is_next_page_disabled = is_next_page_disabled.unwrap();

        if is_next_page_disabled.is_some() {
            break;
        }

        // Click the next page button.
        next_page_button.click()?;
    }

    println!("Finished processing all {} pages.", page_number - 1);

    Ok(())
}

fn handle_network_events(tab: &headless_chrome::Tab) -> Result<()> {
    let network_events = Arc::new(move |event: &Event| {
        if let Event::NetworkRequestWillBeSent(evt) = event {
            if evt.params.request.url.contains("api/qt/clist/get") {
                println!("Intercepted API call event: {:?}", evt);
            }
        }
    });

    tab.add_event_listener(network_events)?;

    Ok(())
}

#[cfg(test)]
mod test {
    use crate::idx::intercept_pagination_api_calls;

    #[tokio::test]
    async fn test_intercept_pagination_api_calls() {
        // println!("result={:?}", result);
        let rs = intercept_pagination_api_calls().await;
        println!("rs={:?}", rs)
    }
}
